//
//  XS_AniLayer.swift
//  XS_Utils
//
//  Created by 韩云智 on 2020/9/10.
//

public func xs_getCenter(_ rect: CGRect) -> CGPoint { CGPoint(x: rect.midX, y: rect.midY) }
public func xs_getLineSpacing(_ str: String, lineSpacing: CGFloat, alignment: NSTextAlignment = .left) -> NSMutableAttributedString {
    let attrString = NSMutableAttributedString(string: str)
    let style = NSMutableParagraphStyle()
    style.lineSpacing = lineSpacing
    style.alignment = alignment
    attrString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: attrString.length))
    return attrString
}

public struct XS_AniParam {
    public var duration: Double
    public var repeatCount: Float
    public var isRemovedOnCompletion: Bool
    public var offset: Double
    public var values: [Any]?
    public var keyTimes: [NSNumber]?
    public var path: CGPath?
    public var repeatDuration: Double
    public var autoreverses: Bool
    public var fillMode: CAMediaTimingFillMode
    public var calculationMode: CAAnimationCalculationMode
    public var timingFunctions: [CAMediaTimingFunction] = []
    
    public init(duration: Double = 0.5,
         repeatCount: Float = 1,
         isRemovedOnCompletion: Bool = true,
         offset: Double = 0,
         repeatDuration: Double = 0,
         autoreverses: Bool = false,
         fillMode: CAMediaTimingFillMode = .removed,
         calculationMode: CAAnimationCalculationMode = .linear) {
        self.duration = duration
        self.repeatCount = repeatCount
        self.isRemovedOnCompletion = isRemovedOnCompletion
        self.offset = offset
        self.repeatDuration = repeatDuration
        self.autoreverses = autoreverses
        self.fillMode = fillMode
        self.calculationMode = calculationMode
    }
}

public extension CALayer {
    public static func getImgLayer(_ img: UIImage?, rect: CGRect) -> Self {
        let imgLayer = Self()
        imgLayer.contents = img?.cgImage
        imgLayer.frame = rect
        return imgLayer
    }
    
    public func changeAnchorPoint(_ point: CGPoint, size: CGSize? = nil) {
        let size = size ?? bounds.size
        anchorPoint = CGPoint(x: point.x/size.width, y: point.y/size.height)
        transform = CATransform3DMakeTranslation(point.x-size.width/2, point.y-size.height/2, 0)
    }
    
    public func corner(radius: CGFloat, bgColor: CGColor, isShadow: Bool = false, sColor: CGColor, offset: CGSize = .zero, effect: CGFloat = 3, opacity: Float = 0.54) {
        cornerRadius = radius
        backgroundColor = bgColor
        guard isShadow else { return }
        shadowColor = sColor
        shadowOpacity = opacity
        shadowOffset = offset
        shadowRadius = effect
    }
}

public extension CALayer {
    public func pauseLayer() {
        let pausedTime = convertTime(CACurrentMediaTime(), from: nil)
        speed = 0
        timeOffset = pausedTime
    }
    public func resumeLayer(_ layerSpeed: Float = 1) {
        let pausedTime = timeOffset
        speed = layerSpeed
        timeOffset = 0
        beginTime = 0
        let timeSincePause = convertTime(CACurrentMediaTime(), from: nil) - pausedTime
        beginTime = timeSincePause
    }
    
    public func runShanShuo(_ scale: Float = 1.1, opacity: Float = 0.8, param: XS_AniParam = XS_AniParam()) {
        var animations: [CAAnimation] = []
        do { // 闪烁
            let ani = CAKeyframeAnimation.getAnimation(.opacity)
            ani.values = [1, opacity, 1]
            animations.append(ani)
        }
        do { // 缩放
            let ani = CAKeyframeAnimation.getAnimation(.scale)
            ani.values = [1, scale, 1]
            animations.append(ani)
        }
        let group = CAAnimationGroup()
        group.animations = animations
        group.duration = param.duration
        group.repeatCount = param.repeatCount
        group.timeOffset = param.offset
        group.isRemovedOnCompletion = param.isRemovedOnCompletion
        add(group, forKey: "_shanshuo")
    }
    
    public func runRepeat(_ keyPath: CAPropertyAnimation.XS_KeyPath, suf: String? = nil, param: XS_AniParam = XS_AniParam(), isRepeat: Bool = true, key: String? = nil) {
        runRepeat(ani: CAKeyframeAnimation.getAnimation(keyPath, suf: suf), param: param, isRepeat: isRepeat, key: key)
    }
    public func runRepeat(ani: CAKeyframeAnimation, param: XS_AniParam = XS_AniParam(), isRepeat: Bool = true, key: String? = nil) {
        ani.path = param.path
        ani.values = param.values
        ani.keyTimes = param.keyTimes
        ani.duration = param.duration
        ani.timeOffset = param.offset
        ani.repeatDuration = param.repeatDuration
        ani.autoreverses = param.autoreverses
        ani.fillMode = param.fillMode
        ani.calculationMode = param.calculationMode
        ani.timingFunctions = param.timingFunctions
        if isRepeat {
            ani.repeatCount = MAXFLOAT
            ani.isRemovedOnCompletion = false
        } else {
            ani.repeatCount = param.repeatCount
            ani.isRemovedOnCompletion = param.isRemovedOnCompletion
        }
        add(ani, forKey: key)
    }
}
